package com.wxxymaker.edu.service;

import com.blade.ioc.annotation.Bean;
import com.blade.ioc.annotation.Inject;
import com.blade.kit.CollectionKit;
import com.wxxymaker.edu.model.entity.Course;
import com.wxxymaker.edu.model.entity.Material;
import com.wxxymaker.edu.model.entity.Task;
import com.wxxymaker.edu.utils.FileUtils;
import com.wxxymaker.edu.utils.TimeUtils;
import io.github.biezhi.anima.Anima;
import io.github.biezhi.anima.core.AnimaQuery;
import io.github.biezhi.anima.core.Joins;
import io.github.biezhi.anima.enums.OrderBy;
import io.github.biezhi.anima.page.Page;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @AUTHOR soft
 * @DATE 2018/9/8 21:05
 * @DESCRIBE 资源业务
 */
@Bean
@Slf4j
public class MaterialService implements Service<Material> {
    @Inject
    private TaskService taskService;

    public boolean down(int mid) {
        return Anima.execute("update material set downs=downs+1 where id=?", mid)>0;
    }

    @Override
    public Material add(Material material) {
        material.setTime(TimeUtils.getTime());
        boolean rollback = Anima.atomic(() -> {
            Integer pk = material.save().asInt();
            material.setId(pk);
        }).catchException(e -> {
            log.error("保存失败! {}", e.getMessage());
        }).isRollback();
        return rollback ? null : material;
    }

    public Material delete(Integer pk, boolean other) {
        Material material = this.delete(pk);
        if (material != null) {
            if (other) {
                FileUtils.deleteByWebPath(material.getPath());
            } else {
                FileUtils.deleteByDownPath(material.getPath(), 4);
            }
        }
        return material;
    }

    @Override
    public Material delete(Object pk) {
        Material material = byId(pk);
        if (material != null) {
            boolean rollback = Anima.atomic(material::delete).catchException(e -> {
                log.error("资料删除失败! {}", e.getMessage());
            }).isRollback();
            return material;
        }
        return null;
    }

    @Override
    public boolean change(Material material) {
        return !Anima.atomic(material::update).catchException(e -> {
            log.error("资料修改失败! {}", e.getMessage());
        }).isRollback();
    }

    @Override
    public Material byId(Object pk) {
        return Anima.select().from(Material.class).byId(pk);
    }

    /**
     * 获取资源文件
     * @param kid  课程id
     * @param type 资源文件类型 1教学课件资源 0课外查看资料
     * @param jc   是否加入课程信息
     */
    public Page<Material> page(int kid, String type, int page, int size, boolean jc) {
        AnimaQuery<Material> join = Anima.select().from(Material.class)
                .where(Material::getCourseId, kid)
                .order(Material::getTime, OrderBy.DESC)
                .join(Joins.with(Task.class)
                        .as(Material::getTask)
                        .on(Material::getTaskId, Task::getId));
        if (jc) {
            join.join(Joins.with(Course.class)
                        .as(Material::getCourse)
                        .on(Material::getCourseId, Course::getId));
        }
        if (type != null) {
            join.where(Material::getType, type);
        }
        Page<Material> page1 = join.page(page, size);
        if (CollectionKit.isNotEmpty(page1.getRows())) {
            for (Material row : page1.getRows()) {
                row.setIsUse(isUse(row.getId()));
            }
            return page1;
        }
        return null;
    }

    /**
     * 更新资料所属的任务id
     * @param mid 资料id
     * @param tid 任务id
     */
    public boolean setTaskId(Integer mid, Integer tid) {
        return Anima.update().from(Material.class)
                .set(Material::getTaskId, tid)
                .where(Material::getId, mid)
                .execute() > 0;
    }

    /**
     * 判断该资料是不是正在被使用
     * @param mid 资料id
     */
    public boolean isUse(int mid) {
        return Anima.select().from(Task.class)
                .where(Task::getMaterialId, mid)
                .count() > 0;
    }

    /**
     * 获取当前课程下 没有被使用的课程教学资源
     * 用来添加任务是选择已有资源使用
     * @param kid 课程id
     */
    public List<Material> getNoUseVideo(int kid) {
        List<Integer> ids = taskService.findAll(kid).stream()
                .map(Task::getMaterialId)
                .collect(Collectors.toList());
        AnimaQuery<Material> query = Anima.select("id, filename, path").from(Material.class)
                .where(Material::getCourseId, kid)
                .where(Material::getType, 1);
        if (CollectionKit.isNotEmpty(ids)) {
            query.where("id NOT").in(ids);
        }
        return query.all();
    }

    public long countBykId(Integer courseId, String type) {
        return Anima.select().from(Material.class)
                .where(Material::getType, type)
                .where(Material::getCourseId, courseId).count();
    }

    /**
     * 课外查看资料，视频由任务统计
     */
    public long countByuId(Integer uid) {
        return Anima.select().from(Material.class)
                .where(Material::getType, 0)
                .where(Material::getCourseId, uid).count();
    }

    public int deleteByKid(Integer kid) {
        return Anima.delete().from(Material.class)
                .where(Material::getCourseId, kid)
                .execute();
    }
}
